home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 40
/
Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso
/
Aminet
/
misc
/
emu
/
msh-156.lha
/
util
/
setmain.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-12-22
|
17KB
|
864 lines
/*-
* $Id: setmain.c,v 1.56 1996/12/22 21:12:51 Rhialto Rel $
* $Log: setmain.c,v $
* Revision 1.56 1996/12/22 21:12:51 Rhialto
* Cosmetics.
*
* Revision 1.56 1996/12/22 00:22:33 Rhialto
* Cosmetics.
*
* Revision 1.55 1993/12/30 23:28:00 Rhialto
* Freeze for MAXON5.
* New GadToolBox (2.0c), and use font-sensitive option.
*
* Revision 1.54 1993/06/24 05:35:45 Rhialto
* DICE 2.07.54R.
*
* Revision 1.53 92/10/25 02:47:12 Rhialto
* Initial revision.
*
* SET MAIN.C
*
* The main file of the MSH settings commodity.
*
* This code is (C) Copyright 1992 by Olaf Seibert. All rights reserved.
* May not be used or copied without a licence.
-*/
#define INTUI_V36_NAMES_ONLY
#include "han.h"
#include "hanconv.h"
#ifndef LIBRARIES_GADTOOLS_H
#include <libraries/gadtools.h>
#endif
#ifndef LIBRARIES_ASL_H
#include <libraries/asl.h>
#endif
#ifndef INTUITION_GADGETCLASS_H
#include <intuition/gadgetclass.h>
#endif
#ifndef DOS_DOS_H
#include <dos/dos.h>
#endif
#ifndef EXEC_MEMORY_H
#include <exec/memory.h>
#endif
#ifndef DOS_DOSEXTENS_H
#include <dos/dosextens.h>
#endif
#ifndef LIBRARIES_COMMODITIES_H
#include <libraries/commodities.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/asl_protos.h>
#include <clib/alib_protos.h>
#include <clib/dos_protos.h>
#include <clib/commodities_protos.h>
#include "setwindow.h"
const char idString[] = "$""VER: MSH-Set $Revision: 1.56 $ $Date: 1996/12/22 21:12:51 $\r\n";
struct Library *AslBase;
struct Library *GadToolsBase;
struct IntuituinBase *IntuitionBase;
struct Library *CxBase;
struct Library *IconBase;
struct PrivateInfo *Private;
char *HandlerName;
struct MsgPort *HandlerPort;
struct MinList MSHList;
struct MSHNode {
struct Node m_Node;
char m_Name[2]; /* 1 for ':', 1 for '\0' */
};
struct FileRequester *FileRequest;
const char OkString[] = "Ok";
const char PanicString[] = "Panic!";
void Show(void);
void Hide(void);
void SetGadgetAttr(int id, ULONG tag, ULONG value);
void UpdateGadgets(struct PrivateInfo *p);
void DeselectHandler(void);
/* Commodities stuff: */
UBYTE **TTypes;
struct NewBroker NewBroker = {
NB_VERSION,
"MSH-Set",
"MSH Settings",
"Change settings of MSH devices",
NBU_UNIQUE | NBU_NOTIFY,
COF_SHOW_HIDE,
0, 0, 0
};
struct MsgPort *BrokerPort;
CxObj *Broker;
#define EVT_HOTKEY 1
/*
* Arg2 -> Arg2, the world turned upside down.
*/
long
dos_packet1a(struct MsgPort *port, long type, long arg2, long arg3)
{
struct StandardPacket *sp;
struct MsgPort *rp;
if ((rp = CreatePort(NULL, 0)) == NULL)
return DOSFALSE;
if ((sp = AllocMem((long) sizeof (*sp), MEMF_PUBLIC | MEMF_CLEAR)) == NULL) {
DeletePort(rp);
return DOSFALSE;
}
sp->sp_Msg.mn_Node.ln_Name = (char *) &sp->sp_Pkt;
sp->sp_Pkt.dp_Link = &sp->sp_Msg;
sp->sp_Pkt.dp_Port = rp;
sp->sp_Pkt.dp_Type = type;
sp->sp_Pkt.dp_Arg2 = arg2;
sp->sp_Pkt.dp_Arg3 = arg3;
PutMsg(port, &sp->sp_Msg);
WaitPort(rp);
GetMsg(rp);
arg2 = sp->sp_Pkt.dp_Arg2;
FreeMem(sp, (long) sizeof (*sp));
DeletePort(rp);
return arg2;
}
struct PrivateInfo *
GetPrivateInfo(struct MsgPort *port, int lockcount)
{
if (port) {
struct PrivateInfo *p;
p = (struct PrivateInfo *)
dos_packet1a(port, ACTION_CURRENT_VOLUME, MSH_MAGIC, lockcount);
if ((long) p == MSH_MAGIC ||
p == NULL ||
p->Revision != PRIVATE_REVISION ||
p->Size != sizeof(*p)) {
/* Incompatible filesystem. */
return NULL;
}
return p;
}
return NULL;
}
/* Commodities stuff: */
void
KillCx(void)
{
if (CxBase) {
if (Broker) {
DeleteCxObjAll(Broker);
Broker = NULL;
}
if (BrokerPort) {
struct Message *msg;
while (msg = GetMsg(BrokerPort)) {
ReplyMsg(msg);
}
DeleteMsgPort(BrokerPort);
BrokerPort = NULL;
}
CloseLibrary(CxBase);
CxBase = NULL;
}
if (IconBase) {
CloseLibrary(IconBase);
IconBase = NULL;
}
}
void
Die(void)
{
Hide();
if (FileRequest)
FreeAslRequest(FileRequest);
KillCx();
if (IntuitionBase) {
CloseLibrary(IntuitionBase);
IntuitionBase = NULL;
}
if (GadToolsBase) {
CloseLibrary(GadToolsBase);
GadToolsBase = NULL;
}
if (AslBase) {
CloseLibrary(AslBase);
AslBase = NULL;
}
exit(0);
}
void
OpenAll(int argc, char **argv)
{
extern struct Library *DOSBase;
int doshow = 1;
NewList((struct List *) &MSHList);
if (DOSBase->lib_Version < 37) {
puts("Sorry, requires at least V37...");
Die();
}
AslBase = OpenLibrary("asl.library", 37L);
if (!AslBase)
Die();
GadToolsBase = OpenLibrary("gadtools.library", 37L);
if (!GadToolsBase)
Die();
IntuitionBase = OpenLibrary("intuition.library", 37L);
if (!IntuitionBase)
Die();
/*
* The following is Commodities stuff.
* We still run if it fails to open, but not if we can't register.
*/
CxBase = OpenLibrary("commodities.library", 37L);
if (CxBase) {
CxObj *filter;
long error = CBERR_OK;
char popup;
IconBase = OpenLibrary("icon.library", 37L);
if (!IconBase)
goto no_cx;
TTypes = ArgArrayInit(argc, argv);
BrokerPort = CreateMsgPort();
NewBroker.nb_Port = BrokerPort;
NewBroker.nb_Pri = ArgInt(TTypes, "CX_PRIORITY", 0);
Broker = CxBroker(&NewBroker, &error);
filter = HotKey(ArgString(TTypes, "CX_POPKEY", "rawkey control alt m"),
BrokerPort, EVT_HOTKEY);
popup = *ArgString(TTypes, "CX_POPUP", "Y");
ArgArrayDone();
/*
* If something goes wrong with commodities, we still run,
* except when we violate the commodity uniqueness.
*/
if (!BrokerPort || !Broker || !filter) {
if (filter)
DeleteCxObjAll(filter);
if (error == CBERR_DUP)
Die();
KillCx();
goto no_cx;
}
AttachCxObj(Broker, filter);
if (!CxObjError(filter)) {
ActivateCxObj(Broker, 1L);
if (popup == 'N') {
doshow = 0;
}
}
}
no_cx:
if (doshow)
Show();
}
void
FindAllMSHs(void)
{
struct DosList *dlist;
dlist = LockDosList(LDF_DEVICES | LDF_READ);
while (dlist = NextDosEntry(dlist, LDF_DEVICES)) {
struct PrivateInfo *p;
if (p = GetPrivateInfo(dlist->dol_Task, 0)) {
char *name;
struct MSHNode *node;
name = (char *) BADDR(dlist->dol_Name);
node = AllocVec(sizeof (*node) + name[0], MEMF_CLEAR);
if (node) {
strncpy(node->m_Name, &name[1], name[0]);
strcpy(node->m_Name + name[0], ":");
node->m_Node.ln_Name = node->m_Name;
AddHead((struct List *) & MSHList, &node->m_Node);
}
}
}
UnLockDosList(LDF_DEVICES | LDF_READ);
}
void
ForgetAllMSHs(void)
{
struct Node *n,
*nn;
n = (struct Node *)MSHList.mlh_Head;
while (nn = n->ln_Succ) {
FreeVec(n);
n = nn;
}
NewList((struct List *) &MSHList);
}
void
Show(void)
{
if (MSHSettingsWnd) {
WindowToFront(MSHSettingsWnd);
return; /* already open */
}
if (SetupScreen())
Die();
if (OpenMSHSettingsWindow())
Die();
if (BrokerPort) {
OnMenu(MSHSettingsWnd, FULLMENUNUM(0, 0, NOSUB)); /* "Hide A-H" */
}
FindAllMSHs();
SetGadgetAttr(GDX_HANDLERS, GTLV_Labels, (ULONG) &MSHList);
UpdateGadgets(Private);
}
void
Hide(void)
{
if (MSHSettingsWnd) {
struct Message *msg;
MSHSettingsLeft = MSHSettingsWnd->LeftEdge;
MSHSettingsTop = MSHSettingsWnd->TopEdge;
while (msg = GetMsg(MSHSettingsWnd->UserPort)) {
ReplyMsg(msg);
}
}
DeselectHandler();
CloseMSHSettingsWindow();
CloseDownScreen();
ForgetAllMSHs();
}
struct Node *
GetNode(struct MinList *l, int num)
{
struct Node *n,
*nn;
n = (struct Node *)l->mlh_Head;
while (num > 0 && (nn = n->ln_Succ)) {
num--;
n = nn;
}
return n;
}
void
SetGadgetAttr(int id, ULONG tag, ULONG value)
{
GT_SetGadgetAttrs(MSHSettingsGadgets[id], MSHSettingsWnd, NULL,
tag, value,
TAG_END);
}
void
UpdateLoadGadget(int i)
{
SetGadgetAttr(GDX_LOAD, GA_Disabled, i == 0);
}
void
DisableGadgets(long i)
{
SetGadgetAttr(GDX_MD40TRACK, GA_Disabled, i);
SetGadgetAttr(GDX_BOOTJMP, GA_Disabled, i);
SetGadgetAttr(GDX_SANITY, GA_Disabled, i);
SetGadgetAttr(GDX_SAN_DEFAULT, GA_Disabled, i);
SetGadgetAttr(GDX_USE_DEFAULT, GA_Disabled, i);
SetGadgetAttr(GDX_CONVERSION, GA_Disabled, i);
SetGadgetAttr(GDX_LOAD, GA_Disabled, i);
}
void
UpdateGadgetsDis(unsigned short i)
{
SetGadgetAttr(GDX_SANITY, GA_Disabled, (i & CHECK_USE_DEFAULT) != 0);
SetGadgetAttr(GDX_SAN_DEFAULT, GA_Disabled,
(i & (CHECK_SANITY|CHECK_USE_DEFAULT)) != CHECK_SANITY);
}
void
UpdateGadgets(struct PrivateInfo *p)
{
if (p) {
long i;
DisableGadgets(FALSE);
i = (*p->DiskIOReq)->iotd_Req.io_Flags;
SetGadgetAttr(GDX_MD40TRACK, GTCB_Checked, (i & IOMDF_40TRACKS) != 0);
i = *p->CheckBootBlock;
UpdateGadgetsDis(i);
SetGadgetAttr(GDX_BOOTJMP, GTCB_Checked, (i & CHECK_BOOTJMP) != 0);
SetGadgetAttr(GDX_SANITY, GTCB_Checked, (i & CHECK_SANITY) != 0);
SetGadgetAttr(GDX_SAN_DEFAULT, GTCB_Checked, (i & CHECK_SAN_DEFAULT) != 0);
SetGadgetAttr(GDX_USE_DEFAULT, GTCB_Checked, (i & CHECK_USE_DEFAULT) != 0);
i = *p->DefaultConversion - ConvNone;
SetGadgetAttr(GDX_CONVERSION, GTCY_Active, i);
UpdateLoadGadget(i);
} else {
DisableGadgets(TRUE);
}
}
void
DeselectHandler(void)
{
if (HandlerPort) {
GetPrivateInfo(HandlerPort, -1);
HandlerPort = NULL;
}
Private = NULL;
HandlerName = NULL;
}
struct PrivateInfo *
SelectHandler(char *name)
{
struct MsgPort *filehandler;
struct PrivateInfo *p;
DeselectHandler();
filehandler = DeviceProc(name);
if (filehandler == 0) {
struct EasyStruct er = {
sizeof er, 0, PanicString,
"Cannot find\n%s",
OkString
};
EasyRequest(MSHSettingsWnd, &er, NULL, name);
}
p = GetPrivateInfo(filehandler, 1);
UpdateGadgets(p);
if (p) {
HandlerName = name;
HandlerPort = filehandler;
}
Private = p;
return p;
}
unsigned char *
InstallTable(unsigned char **ptr, unsigned char *init)
{
Forbid();
if (init) {
if (*ptr == NULL)
*ptr = AllocMem(256L, 0L);
if (*ptr != NULL)
CopyMem(init, *ptr, 256L);
} else if (*ptr != NULL) {
FreeMem(*ptr, 256L);
*ptr = NULL;
}
Permit();
return *ptr;
}
void
DoLoad(long qualifier)
{
struct FileRequester *fr;
struct PrivateInfo *p;
int conversion;
p = Private;
if (!p) {
return;
}
conversion = *p->DefaultConversion;
if (conversion >= ConvFence)
conversion = ConvNone;
if (conversion == ConvNone ||
conversion > p->NumConversions) {
struct EasyStruct er = {
sizeof er, 0, PanicString,
"Incorrect conversion %lc\nfor %s:",
OkString
};
EasyRequest(MSHSettingsWnd, &er, NULL,
(APTR)('@'+conversion), HandlerName);
return;
}
conversion -= ConvNone + 1; /* Make it 0-based */
/* If hit with shift, unload existing table */
if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)) {
struct EasyStruct er = {
sizeof er, 0, NULL,
"Reset %lc-conversion table?",
"Ok|Cancel"
};
long reply;
reply = EasyRequest(MSHSettingsWnd, &er, NULL,
(APTR)('@' + ConvNone + 1 + conversion));
if (reply) {
InstallTable(p->Table[conversion].to, NULL);
InstallTable(p->Table[conversion].from, NULL);
}
return;
}
if (FileRequest == NULL) {
FileRequest = (struct FileRequester *)
AllocAslRequestTags(ASL_FileRequest,
ASL_Hail, "Select a conversion table",
TAG_DONE);
}
if (fr = FileRequest) {
unsigned char table[256];
BPTR file;
if (AslRequest(fr, NULL) == 0) {
goto end;
}
strncpy(table, fr->rf_Dir, sizeof (table) - 1);
AddPart(table, fr->rf_File, sizeof (table) - 1);
file = Open(table, MODE_OLDFILE);
if (file == 0) {
struct EasyStruct er = {
sizeof er, 0, NULL,
"Cannot open table\n%s",
OkString
};
EasyRequest(MSHSettingsWnd, &er, NULL, table);
goto end;
}
if (Read(file, table, sizeof (table)) == 256)
InstallTable(p->Table[conversion].to, table);
if (Read(file, table, sizeof (table)) == 256)
InstallTable(p->Table[conversion].from, table);
Close(file);
end:
}
}
int
DoGadget(struct IntuiMessage *imsg)
{
struct Gadget *gd;
int id;
struct PrivateInfo *p;
gd = (struct Gadget *) imsg->IAddress;
id = gd->GadgetID;
switch (id) {
case GD_HANDLERS:
{
struct Node *n;
n = GetNode(&MSHList, imsg->Code);
SelectHandler(n->ln_Name);
}
return 0;
case GD_LOAD:
DoLoad(imsg->Qualifier);
return 0;
}
p = Private;
if (!p)
return 0;
/* Following all assume Private is valid */
switch (id) {
case GD_MD40TRACK:
{
struct IOExtTD *io;
if (io = *p->DiskIOReq) {
if (gd->Flags & GFLG_SELECTED) {
io->iotd_Req.io_Flags |= IOMDF_40TRACKS;
} else {
io->iotd_Req.io_Flags &= ~IOMDF_40TRACKS;
}
}
}
break;
case GD_BOOTJMP:
{
short *f = p->CheckBootBlock;
if (gd->Flags & GFLG_SELECTED) {
*f |= CHECK_BOOTJMP;
} else {
*f &= ~CHECK_BOOTJMP;
}
}
break;
case GD_SANITY:
{
short *f = p->CheckBootBlock;
if (gd->Flags & GFLG_SELECTED) {
*f |= CHECK_SANITY;
} else {
*f &= ~CHECK_SANITY;
}
UpdateGadgetsDis(*f);
}
break;
case GD_SAN_DEFAULT:
{
short *f = p->CheckBootBlock;
if (gd->Flags & GFLG_SELECTED) {
*f |= CHECK_SAN_DEFAULT;
} else {
*f &= ~CHECK_SAN_DEFAULT;
}
}
break;
case GD_USE_DEFAULT:
{
short *f = p->CheckBootBlock;
if (gd->Flags & GFLG_SELECTED) {
*f |= CHECK_USE_DEFAULT;
} else {
*f &= ~CHECK_USE_DEFAULT;
}
UpdateGadgetsDis(*f);
}
break;
case GD_CONVERSION:
*p->DefaultConversion = imsg->Code + ConvNone;
UpdateLoadGadget(imsg->Code);
break;
}
return 0;
}
void
MainLoop(void)
{
long waitmask;
long windowmask;
long brokermask;
long mask;
int done;
top:
done = 0;
if (MSHSettingsWnd)
windowmask = 1L << MSHSettingsWnd->UserPort->mp_SigBit;
else
windowmask = 0;
if (BrokerPort)
brokermask = 1L << BrokerPort->mp_SigBit;
else
brokermask = 0;
waitmask = windowmask | brokermask | SIGBREAKF_CTRL_C;
while (!done) {
mask = Wait(waitmask);
if (mask & SIGBREAKF_CTRL_C) {
done = 1;
break;
}
/*
* Note that this part won't be reachable if
* commodities failed to open.
*/
if (mask & brokermask) {
CxMsg *cxmsg;
while (cxmsg = (CxMsg *)GetMsg(BrokerPort)) {
int id;
int type;
id = CxMsgID(cxmsg);
type = CxMsgType(cxmsg);
ReplyMsg((struct Message *)cxmsg);
switch (type) {
case CXM_IEVENT:
if (id == EVT_HOTKEY) {
goto show;
}
break;
case CXM_COMMAND:
switch (id) {
case CXCMD_DISABLE:
ActivateCxObj(Broker, 0L);
break;
case CXCMD_ENABLE:
ActivateCxObj(Broker, 1L);
break;
case CXCMD_APPEAR:
case CXCMD_UNIQUE:
show:
Show();
goto top;
case CXCMD_DISAPPEAR:
hide:
Hide();
goto top;
case CXCMD_KILL:
done = 1;
break;
}
break;
}
}
}
if (mask & windowmask) {
struct IntuiMessage *imsg;
struct IntuiMessage msg;
while (imsg = GT_GetIMsg(MSHSettingsWnd->UserPort)) {
msg = *imsg;
GT_ReplyIMsg(imsg);
switch (msg.Class) {
case IDCMP_CLOSEWINDOW:
/*
* Commodities only hide when you try to close them.
*/
if (BrokerPort) {
goto hide;
} else {
done = 1;
}
break;
case IDCMP_GADGETUP:
done = DoGadget(&msg);
break;
case IDCMP_MENUPICK:
switch (ITEMNUM(msg.Code)) {
case 0: /* Hide */
goto hide;
break;
case 1: /* Quit */
done = 1;
break;
}
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(MSHSettingsWnd);
GT_EndRefresh(MSHSettingsWnd, TRUE);
break;
case IDCMP_DISKINSERTED:
SelectHandler(HandlerName);
UpdateGadgets(Private);
break;
}
}
}
}
}
int
main(int argc, char **argv)
{
OpenAll(argc, argv);
MainLoop();
Die();
return 0;
}
#ifndef WORKBENCH_STARTUP_H
#include <workbench/startup.h>
#endif
int
wbmain(struct WBStartup *wbs)
{
int rc;
long lock;
if (wbs->sm_ArgList)
lock = CurrentDir(wbs->sm_ArgList->wa_Lock);
rc = main(0, (char **)wbs);
if (wbs->sm_ArgList)
CurrentDir(lock);
return rc;
}